home *** CD-ROM | disk | FTP | other *** search
/ TOS Silver 2000 / TOS Silver 2000.iso / programm / MM2_DEV / S / LAN / LAN_V1 < prev    next >
Encoding:
Text File  |  1991-05-17  |  36.7 KB  |  3 lines

  1. ⓪ MODULE LANMonitor; (*$H+,Z+,R-*)⓪ ⓪ (*⓪ IMPORT TOSDebug;⓪ *)⓪ ⓪ IMPORT SYSTEM;⓪ FROM SYSTEM IMPORT ASSEMBLER, BYTE;⓪ ⓪ IMPORT MOSGlobals, PrgCtrl;⓪ IMPORT RandomGen;⓪ ⓪ IMPORT TOSIO; (*$E MOS *)⓪ IMPORT InOut, FuncStrings, StrConv;⓪ FROM InOut IMPORT WriteLn, Write, WriteCard, ReadCard, ReadLCard, Read,⓪0GotoXY, WritePg, WriteString, WriteHex, WriteLHex,⓪0KeyPressed, Done, WriteNum, WriteLNum;⓪ ⓪ FROM GEMDOS IMPORT Super;⓪ IMPORT VT52; FROM VT52 IMPORT Codes;⓪ IMPORT XBIOS;⓪ FROM Storage IMPORT ALLOCATE;⓪ ⓪ ⓪ (*****************************************************************************)⓪ ⓪ MODULE TimerA;⓪ (*$L-*)⓪ ⓪ (*⓪!* Der MFP ist mit 2.4576 MHz getaktet.⓪!*)⓪ ⓪ FROM SYSTEM IMPORT ASSEMBLER;⓪ ⓪ EXPORT QUALIFIED Init, Delay1Bit, Delay1Byte,⓪(DelayµsUntil, DelayBytesUntil, StopProc;⓪ ⓪ TYPE    StopProc = PROCEDURE  (): BOOLEAN;⓪ ⓪ PROCEDURE Delay1Bit;⓪"BEGIN⓪$ASSEMBLER⓪(; Delay: 1.5 * bitTime (6.51µs) = 16 Zyklen⓪(MOVEA.W #$FA00,A0⓪(MOVE.B  #$DF,$0B(A0)    ; IPRA: Clear Timer-A Pending Bit⓪(MOVE.B  #4,$1F(A0)      ; TADR: Set Timer Count⓪(MOVE.B  #1,$19(A0)      ; TACR: Timer Start (Teiler: 1/4)⓪%l: BTST    #5,$0B(A0)      ; IPRA⓪(BEQ     l⓪(MOVE.B  #$00,$19(A0)    ; TACR: Timer Stop⓪$END⓪"END Delay1Bit;⓪ ⓪ PROCEDURE Delay1Byte;⓪"BEGIN⓪$ASSEMBLER⓪(; Delay: 1.5 * byteTime (39µs) = 58 Zyklen⓪(MOVEA.W #$FA00,A0⓪(MOVE.B  #$DF,$0B(A0)    ; IPRA: Clear Timer-A Pending Bit⓪(MOVE.B  #35,$1F(A0)     ; TADR: Set Timer Count⓪(MOVE.B  #1,$19(A0)      ; TACR: Timer Start (Teiler: 1/4)⓪%l: BTST    #5,$0B(A0)      ; IPRA⓪(BEQ     l⓪(MOVE.B  #$00,$19(A0)    ; TACR: Timer Stop⓪$END⓪"END Delay1Byte;⓪ ⓪ PROCEDURE DelayBytesUntil (n: CARDINAL; stop: StopProc; condition: BOOLEAN): BOOLEAN;⓪"BEGIN⓪$ASSEMBLER⓪(; Delay: n * 1.5 * byteTime (39µs) = n * 58.5 Zyklen⓪(; RETURN: FALSE, wenn Zeit abgelaufen,⓪(;         TRUE, wenn stop()=condition lieferte⓪(MOVEM.L D3-D5/A4/A6,-(A7)⓪(MOVE.W  -(A3),D5        ; condition⓪(MOVE.L  -(A3),D4        ; stop (static link)⓪(MOVE.L  -(A3),A4        ; stop (addr)⓪(MOVE.W  -(A3),D3        ; n⓪(MOVEA.W #$FA00,A6⓪(MOVE.B  #$DF,$0B(A6)    ; IPRA: Clear Timer-A Pending Bit⓪(MOVE.B  #36,$1F(A6)     ; TADR: Set Timer Count⓪(MOVE.B  #1,$19(A6)      ; TACR: Timer Start (Teiler: 1/4)⓪(BRA     c⓪%l: BTST    #5,$0B(A6)      ; IPRA⓪(BNE     g⓪(MOVE.L  D4,D2⓪(JSR     (A4)⓪(CMP.W   D0,D5⓪(BNE     l⓪(MOVEQ   #1,D0⓪(BRA     e⓪%g: MOVE.B  #$DF,$0B(A6)    ; IPRA: Clear Timer-A Pending Bit⓪%c: DBRA    D3,l⓪(MOVEQ   #0,D0⓪%e: MOVE.B  #$00,$19(A6)    ; TACR: Timer Stop⓪(MOVEM.L (A7)+,D3-D5/A4/A6⓪$END⓪"END DelayBytesUntil;⓪ ⓪ PROCEDURE DelayµsUntil (n: CARDINAL; stop: StopProc; condition: BOOLEAN): BOOLEAN;⓪"BEGIN⓪$ASSEMBLER⓪(; Delay: n µs⓪(; RETURN: FALSE, wenn Zeit abgelaufen,⓪(;         TRUE, wenn stop()=condition lieferte⓪(MOVEM.L D4-D5/A4/A6,-(A7)⓪(MOVE.W  -(A3),D5        ; condition⓪(MOVE.L  -(A3),D4        ; stop (static link)⓪(MOVE.L  -(A3),A4        ; stop (addr)⓪(MOVE.W  -(A3),D0        ; n⓪(LSR     #2,D0           ; n DIV 4⓪(MOVEA.W #$FA00,A6⓪(MOVE.B  #$DF,$0B(A6)    ; IPRA: Clear Timer-A Pending Bit⓪(MOVE.B  D0,$1F(A6)      ; TADR: Set Timer Count⓪(MOVE.B  #2,$19(A6)      ; TACR: Timer Start (Teiler: 1/10)⓪%l: MOVE.L  D4,D2⓪(JSR     (A4)⓪(CMP.W   D0,D5⓪(BEQ     t⓪(BTST    #5,$0B(A6)      ; IPRA⓪(BEQ     l⓪(MOVEQ   #0,D0⓪(BRA     e⓪%t: MOVEQ   #1,D0⓪%e: MOVE.B  #$00,$19(A6)    ; TACR: Timer Stop⓪(MOVEM.L (A7)+,D4-D5/A4/A6⓪$END⓪"END DelayµsUntil;⓪ ⓪ PROCEDURE Delay (teiler, count: CARDINAL);⓪"BEGIN⓪$ASSEMBLER⓪(MOVEA.W #$FA00,A0⓪(MOVE.B  #$DF,$0B(A0)    ; IPRA: Clear Timer-A Pending Bit⓪(MOVE.W  -(A3),D0⓪(MOVE.W  -(A3),D1⓪(MOVE.B  D0,$1F(A0)      ; TADR: Set Timer Count⓪(MOVE.B  D1,$19(A0)      ; TACR: Timer Start⓪%l: BTST    #5,$0B(A0)      ; IPRA⓪(BEQ     l⓪(MOVE.B  #$00,$19(A0)    ; TACR: Timer Stop⓪$END⓪"END Delay;⓪ ⓪ PROCEDURE Start (teiler, count: CARDINAL);⓪"BEGIN⓪$ASSEMBLER⓪(MOVEA.W #$FA00,A0⓪(MOVE.B  #$DF,$0B(A0)    ; IPRA: Clear Timer-A Pending Bit⓪(MOVE.W  -(A3),D0⓪(MOVE.W  -(A3),D1⓪(MOVE.B  D0,$1F(A0)      ; TADR: Set Timer Count⓪(MOVE.B  D1,$19(A0)      ; TACR: Timer Start⓪%l: END⓪"END Start;⓪ ⓪ PROCEDURE Stop;⓪"BEGIN⓪$ASSEMBLER⓪(MOVE.B  #$00,$FFFA19    ; TACR: Timer Stop⓪$END⓪"END Stop;⓪ ⓪ PROCEDURE Down (): BOOLEAN;⓪"BEGIN⓪$ASSEMBLER⓪(BTST    #5,$FFFA0B      ; IPRA⓪(BEQ     no⓪(BCLR    #5,$FFFA0B      ; IPRA: Clear Timer-A Pending Bit⓪(MOVEQ   #1,D0⓪(RTS⓪$no: CLR     D0⓪$END⓪"END Down;⓪ ⓪ (* nur mit dieser optimierten Schleife sind auf dem Mega STE die⓪!* 1.5*bitTime zu messen:⓪"Start (1,4);⓪"ASSEMBLER⓪(MOVE.L  n,D1⓪(MOVE.L  l,D0⓪(MOVEQ   #5,D2⓪(LEA     $FFFA0B,A0⓪$lo: BTST    D2,(A0)         ; IPRA⓪(BEQ     lo⓪(BCLR    D2,(A0)         ; IPRA: Clear Timer-A Pending Bit⓪(ADDQ.L  #1,D1⓪(CMP.L   hz200,D0⓪(BHI     lo⓪(MOVE.L  D1,n⓪"END;⓪ *)⓪ ⓪ PROCEDURE Init;⓪"BEGIN⓪$ASSEMBLER⓪(MOVEA.W #$FA00,A0⓪(MOVE.B  #$00,$19(A0)    ; TACR: Timer Stop⓪(ANDI.B  #$DF,$13(A0)    ; IMRA: Mask Timer A IR⓪(ORI.B   #$20,$07(A0)    ; IERA: Enable Timer-A Pending Bit⓪(MOVE.B  #$DF,$0B(A0)    ; IPRA: Clear Timer-A Pending Bit⓪$END⓪"END Init;⓪ ⓪ (*$L=*)⓪ END (* MODULE *) TimerA;⓪ ⓪ (*****************************************************************************)⓪ ⓪ MODULE SCCDMA;⓪ (*$L-*)⓪ ⓪ FROM SYSTEM IMPORT WORD, ADDRESS, ASSEMBLER;⓪ ⓪ EXPORT QUALIFIED SetAddr, Addr, SetCount, Count, SetIn, SetOut, Enable,⓪1Finished;⓪ ⓪ CONST DMA = $FFFF8C00;⓪ ⓪ PROCEDURE SetAddr (ad: ADDRESS);⓪"BEGIN⓪$ASSEMBLER⓪(MOVE.L  -(A3),D0⓪(MOVE.W  #DMA,A0⓪(MOVEP.L D0,1(A0)⓪$END⓪"END SetAddr;⓪ ⓪ PROCEDURE Addr (): ADDRESS;⓪"BEGIN⓪$ASSEMBLER⓪(MOVE.W  #DMA,A0⓪(MOVEP.L 1(A0),D0⓪$END⓪"END Addr;⓪ ⓪ PROCEDURE SetCount (n: LONGCARD);⓪"BEGIN⓪$ASSEMBLER⓪(MOVE.L  -(A3),D0⓪(MOVE.W  #DMA,A0⓪(MOVEP.L D0,9(A0)⓪$END⓪"END SetCount;⓪ ⓪ PROCEDURE Count (): LONGCARD;⓪"BEGIN⓪$ASSEMBLER⓪(MOVE.W  #DMA,A0⓪(MOVEP.L 9(A0),D0⓪$END⓪"END Count;⓪ ⓪ PROCEDURE SetControl (n: WORD);⓪"BEGIN⓪$ASSEMBLER⓪(MOVE.W  -(A3),D0⓪(MOVE.B  D0,DMA+$15⓪$END⓪"END SetControl;⓪ ⓪ PROCEDURE Control (): WORD;⓪"BEGIN⓪$ASSEMBLER⓪(MOVEQ   #0,D0⓪(MOVE.B  DMA+$15,D0⓪$END⓪"END Control;⓪ ⓪ PROCEDURE SetOut;⓪"BEGIN⓪$ASSEMBLER⓪(BSET    #0,DMA+$15⓪$END⓪"END SetOut;⓪ ⓪ PROCEDURE SetIn;⓪"BEGIN⓪$ASSEMBLER⓪(BCLR    #0,DMA+$15⓪$END⓪"END SetIn;⓪ ⓪ PROCEDURE Enable;⓪"BEGIN⓪$ASSEMBLER⓪(BSET    #1,DMA+$15⓪$END⓪"END Enable;⓪ ⓪ PROCEDURE Disable;⓪"BEGIN⓪$ASSEMBLER⓪(BCLR    #1,DMA+$15⓪$END⓪"END Disable;⓪ ⓪ PROCEDURE Finished (): BOOLEAN;⓪"BEGIN⓪$ASSEMBLER⓪(MOVE.B  DMA+$15,D0⓪(ANDI.W  #11000000%,D0   ; bus error oder zero count?⓪(SNE     D0⓪(ANDI.W  #1,D0⓪$END⓪"END Finished;⓪ ⓪ (*$L=*)⓪ END (* MODULE *) SCCDMA;⓪ ⓪ (*****************************************************************************)⓪ ⓪ MODULE SCC;⓪ (*$L-*)⓪ ⓪ FROM SYSTEM IMPORT WORD, ADDRESS, ASSEMBLER;⓪ ⓪ IMPORT Super;⓪ FROM PrgCtrl IMPORT TermCarrier, CatchProcessTerm;⓪ FROM MOSGlobals IMPORT MemArea;⓪ ⓪ EXPORT QUALIFIED Reg, SetReg, Reset, CTLA;⓪ ⓪ CONST CTLA = $FFFF8C81;⓪ ⓪ PROCEDURE Reg (n: CARDINAL): CARDINAL;⓪"BEGIN⓪$ASSEMBLER⓪(MOVE    SR,-(A7)⓪(MOVE    #$2500,SR⓪(MOVEA.W #CTLA,A1⓪(MOVE.W  -(A3),D0⓪(BEQ     read0⓪(MOVE.B  D0,(A1)          ; SCC A control⓪&read0:⓪(MOVE.B  (A1),D0⓪(MOVE    (A7)+,SR⓪$END;⓪"END Reg;⓪ ⓪ PROCEDURE SetReg (no, value: CARDINAL);⓪"BEGIN⓪$ASSEMBLER⓪(MOVE    SR,-(A7)⓪(MOVE    #$2500,SR⓪(MOVEA.W #CTLA,A1⓪(MOVE.W  -(A3),D1        ; value⓪(MOVE.W  -(A3),D0        ; no⓪(BEQ     write0⓪(MOVE.B  D0,(A1)         ; SCC A control⓪&write0:⓪(MOVE.B  D1,(A1)⓪(MOVE    (A7)+,SR⓪$END;⓪"END SetReg;⓪ ⓪ (*$L=*)⓪ ⓪ (****** Vorsicht: ab hier $L+ ******)⓪ ⓪ PROCEDURE Reset;⓪"BEGIN⓪$SetReg (9, $C0);⓪"END Reset;⓪ ⓪ PROCEDURE term;⓪"VAR ssp: LONGCARD;⓪"BEGIN⓪$ssp:= Super (0);⓪$SetReg (9, $C0);⓪$ssp:= Super (ssp)⓪"END term;⓪ ⓪ VAR carrier: TermCarrier;⓪ ⓪ BEGIN⓪"CatchProcessTerm (carrier, term, MemArea{NIL,0});⓪ END (* MODULE *) SCC;⓪ ⓪ (*****************************************************************************)⓪ ⓪ MODULE ALAP;⓪ ⓪ FROM SYSTEM IMPORT ADR, ASSEMBLER, BITNUM, BYTE, WORD, LONGWORD, ADDRESS, SHIFT;⓪ IMPORT SCC, SCCDMA, TimerA;⓪ FROM SCC IMPORT CTLA;⓪ IMPORT RandomGen;⓪ FROM XBIOS IMPORT GIOffBit;⓪ IMPORT Super, ALLOCATE;⓪ ⓪ (* I/O-Routinen für Testausgaben *)⓪ IMPORT InOut;⓪ FROM FuncStrings IMPORT ConcStr;⓪ FROM StrConv IMPORT CardToStr;⓪ ⓪ EXPORT QUALIFIED⓪"WriteFrame, WriteStatus,⓪"Init, TransmitStatus, TransmitPacket, ReceiveFrame, ReceivePacket,⓪"myAddress, fAdrValid, fAdrInUse, FramesReceived, Interrupts,⓪"maxIFGtime, test, NewPacketBuffer, FrameStatus, anAddress, aLAPtype,⓪"aDataField,⓪"aFrame, aPacket, ptrPacket, maxDataSize, headPacket, tailPacket;⓪ ⓪ ⓪ CONST   minFrameSize = 3;⓪(maxFrameSize = 605;⓪(maxDataSize = 600;⓪(⓪((* alle Zeitwerte sind in µs angegeben *)⓪(bitTime = 5 (* 4.34 *);⓪(byteTime = 39;⓪(minIDGtime = 400;⓪(IDGslottime = 100;⓪(maxIFGtime = 200; (* ist für ENQ->ACK offenbar zu klein. 400-600 besser *)⓪(⓪(maxDefers = 32;⓪(maxCollsns = 32;⓪(lapENQ = BYTE($81);⓪(lapACK = BYTE($82);⓪(lapRTS = BYTE($84);⓪(lapCTS = BYTE($85);⓪(wksTries = 2 (* 20!! *);⓪(⓪(rxEnable = $DD;⓪(setRTS   = $62;⓪(txEnable = $6B;⓪ ⓪ TYPE    TransmitStatus = (transmitOK, excessDefers, excessCollsns, dupAddress);⓪(ReceiveStatus = (receiveOK, receiving, nullReceive, frameError);⓪(FrameStatus = (noFrame, lapDATAframe, lapENQframe, lapACKframe,⓪(lapRTSframe, lapCTSframe, badframeCRC, badframeSize, badframeType,⓪(overrunError, underrunError, undefined);⓪(⓪(bitVector = SET OF BITNUM[0..7];⓪(octet = BYTE;⓪(anAddress = octet;⓪(aLAPtype = octet;⓪(aDataField = ARRAY [1..maxDataSize] OF octet;⓪(ptrDataField = POINTER TO aDataField;⓪ ⓪(frameInterpretation = (raw, structured);⓪(aFrame = RECORD⓪3CASE :frameInterpretation OF⓪5raw:⓪7rawData: ARRAY [1..maxFrameSize] OF octet|⓪5structured:⓪7dstAddr: anAddress;⓪7srcAddr: anAddress;⓪7lapType: aLAPtype;⓪7dataField: aDataField⓪3END⓪1END;⓪ ⓪(ptrPacket = POINTER TO aPacket;⓪(aPacket = RECORD⓪4status: FrameStatus;⓪4length: [0..maxFrameSize];⓪4next  : ptrPacket;⓪4frame : aFrame;⓪4no    : CARDINAL;⓪2END;⓪ ⓪ VAR     myAddress: anAddress;⓪(backoff: INTEGER;⓪(fAdrValid: BOOLEAN;⓪(fAdrInUse: BOOLEAN;⓪(fCTSexpected: BOOLEAN;⓪(deferCount, collsnCount: INTEGER;⓪(deferHistory, collsnHistory: bitVector;⓪(outgoingLength: INTEGER;⓪(outgoingPacket: aFrame;⓪(⓪(packetBuffers: CARDINAL;⓪(tailPacket: ptrPacket;  (* zeigt aufs älteste gültige Paket *)⓪(headPacket: ptrPacket;  (* zeigt hinter jüngstes Paket *)⓪((* wenn head = tail, stehen keine neuen Pakete an. *)⓪(⓪(FramesReceived, Interrupts: CARDINAL;⓪(⓪(test: BOOLEAN;⓪(⓪(IR_Vector [$360]: PROC;⓪ ⓪ (*$L-*)⓪ ⓪ PROCEDURE And (a,b:CARDINAL): CARDINAL;⓪"BEGIN⓪$ASSEMBLER⓪(MOVE.W  -(A3),D0⓪(AND.W   -(A3),D0⓪$END⓪"END And;⓪ ⓪ PROCEDURE Or (a,b:CARDINAL): CARDINAL;⓪"BEGIN⓪$ASSEMBLER⓪(MOVE.W  -(A3),D0⓪(OR.W    -(A3),D0⓪$END⓪"END Or;⓪ ⓪ PROCEDURE BClr (value, bitno:CARDINAL): CARDINAL;⓪"BEGIN⓪$ASSEMBLER⓪(MOVE.W  -(A3),D1⓪(MOVE.W  -(A3),D0⓪(BCLR    D1,D0⓪$END⓪"END BClr;⓪ ⓪ PROCEDURE BSet (value, bitno:CARDINAL): CARDINAL;⓪"BEGIN⓪$ASSEMBLER⓪(MOVE.W  -(A3),D1⓪(MOVE.W  -(A3),D0⓪(BSET    D1,D0⓪$END⓪"END BSet;⓪ ⓪ PROCEDURE In (bitno, value: CARDINAL): BOOLEAN;⓪"BEGIN⓪$ASSEMBLER⓪(MOVE.W  -(A3),D0⓪(MOVE.W  -(A3),D1⓪(BTST    D1,D0⓪(SNE     D0⓪(ANDI    #1,D0⓪$END⓪"END In;⓪ ⓪ PROCEDURE BitCount (bits: BYTE): INTEGER;⓪"BEGIN⓪$ASSEMBLER⓪(SUBQ.L  #1,A3⓪(MOVE.B  -(A3),D1⓪(MOVEQ   #0,D0⓪(MOVEQ   #7,D2⓪%l: LSR.B   #1,D1⓪(BCC     c⓪(ADDQ    #1,D0⓪%c: DBRA    D2,l⓪$END⓪"END BitCount;⓪ ⓪ (*$L+*)⓪ ⓪ (* ------------- Beginn Low-Level ------------------- *)⓪ ⓪ PROCEDURE carrierSense (): BOOLEAN;⓪"(*$L-*)⓪"BEGIN⓪$(* RETURN NOT (4 IN BITSET(SCC.Reg(0))) *)⓪$ASSEMBLER⓪(BTST    #4,CTLA⓪(SEQ     D0⓪(ANDI    #1,D0⓪$END⓪"END carrierSense;⓪"(*$L=*)⓪ ⓪ PROCEDURE missingClock (): BOOLEAN;⓪"(*$L-*)⓪"BEGIN⓪$(* RETURN (7 IN BITSET(SCC.Reg(10))) *)⓪$ASSEMBLER⓪(MOVEA.W #CTLA,A1⓪(MOVE.B  #10,(A1)⓪(TST.B   (A1)            ; RR10⓪(SMI     D0⓪(ANDI    #1,D0⓪$END⓪"END missingClock;⓪"(*$L=*)⓪ ⓪ PROCEDURE resetError;⓪"BEGIN⓪$SCC.SetReg (0, $30)⓪"END resetError;⓪ ⓪ PROCEDURE setAddress (n: BYTE);⓪"BEGIN⓪$SCC.SetReg(6, ORD(n))⓪"END setAddress;⓪ ⓪ PROCEDURE enableRx;⓪"BEGIN⓪$SCC.SetReg(3, rxEnable)⓪"END enableRx;⓪ ⓪ PROCEDURE resetRx;⓪"BEGIN⓪$ASSEMBLER⓪(MOVEA.W #CTLA,A1⓪(; resetRx⓪(MOVE.B  #3,(A1)⓪(MOVE.B  #$D0,(A1)       ; disableRx⓪(MOVEQ   #2,D0⓪&flushFIFO:⓪(TST.B   2(A1)⓪(DBRA    D0,flushFIFO⓪(⓪(MOVE.B  #3,(A1)⓪(MOVE.B  #rxEnable,(A1)  ; enableRx⓪(; reset error⓪(MOVE.B  #$30,(A1)⓪(⓪(; MOVE.B  #1,(A1)⓪(; MOVE.B  #$08,(A1)         ; enable IR on first Rx⓪(⓪(; MOVE.B  #$20,(A1)         ; enable IR on next Rx⓪$END⓪"END resetRx;⓪ ⓪ PROCEDURE resetMissingClock ();⓪"BEGIN⓪$SCC.SetReg(14, $41);⓪"END resetMissingClock;⓪ ⓪ (* ------------- Ende Low-Level ------------------- *)⓪ ⓪ PROCEDURE min (a,b: INTEGER): INTEGER;⓪"BEGIN⓪$IF a < b THEN RETURN a ELSE RETURN b END⓪"END min;⓪ ⓪ PROCEDURE max (a,b: INTEGER): INTEGER;⓪"BEGIN⓪$IF a > b THEN RETURN a ELSE RETURN b END⓪"END max;⓪ ⓪ PROCEDURE random (maxMin1: INTEGER): INTEGER;⓪"BEGIN⓪$RETURN RandomGen.RandomCard (0, maxMin1-1)⓪"END random;⓪ ⓪ PROCEDURE Wr (REF s: ARRAY OF CHAR);⓪"BEGIN⓪$InOut.WriteString (s);⓪$InOut.WriteLn;⓪"END Wr;⓪ ⓪ PROCEDURE WriteFrame (REF packet: aPacket; no: CARDINAL);⓪"VAR n: CARDINAL;⓪"BEGIN⓪$FOR n:= 1 TO 5 DO⓪&IF n > packet.length THEN⓪(InOut.WriteString ('   ');⓪&ELSE⓪(InOut.WriteHex (LONG (packet.frame.rawData [n]), 3);⓪&END⓪$END;⓪$FOR n:= 6 TO no DO⓪&IF n <= packet.length THEN⓪(InOut.WriteHex (LONG (packet.frame.rawData [n]), 3);⓪(IF (ORD (packet.frame.rawData [n]) >= 32) AND⓪+(ORD (packet.frame.rawData [n]) < 128) THEN⓪*InOut.Write ('/');⓪*InOut.Write (CHAR(packet.frame.rawData [n]));⓪(END⓪&END⓪$END;⓪$InOut.WriteString (' ');⓪"END WriteFrame;⓪ ⓪ PROCEDURE WriteStatus (status: FrameStatus);⓪"BEGIN⓪$CASE status OF⓪&|badframeCRC: InOut.WriteString ('>badframeCRC<')⓪&|badframeSize: InOut.WriteString ('>badframeSize<');⓪&|badframeType: InOut.WriteString ('>badframeType<')⓪&|overrunError: InOut.WriteString ('>overrunError<')⓪&|underrunError: InOut.WriteString ('>underrunError<')⓪&|lapACKframe: InOut.WriteString ('>ACKframe<')⓪&|lapENQframe: InOut.WriteString ('>ENQframe<');⓪&|lapRTSframe: InOut.WriteString ('>RTSframe<');⓪&|lapDATAframe: InOut.WriteString ('>DATAframe<');⓪&|noFrame: InOut.WriteString ('no frame!');⓪$ELSE⓪&InOut.WriteString ('unknown frame!');⓪$END;⓪"END WriteStatus;⓪ ⓪ (* --------------------------- *)⓪ ⓪ FORWARD AcquireAddress (hint: BYTE; server: BOOLEAN);⓪ FORWARD TransmitPacket (dstParam: anAddress; typeParam: aLAPtype; REF dataParam: aDataField; dataLength: INTEGER): TransmitStatus;⓪ FORWARD TransmitLinkMgmt (): TransmitStatus;⓪ FORWARD TransmitFrame (REF frame: aFrame; framesize: CARDINAL);⓪ FORWARD ReceiveFrame (VAR packet: ptrPacket): FrameStatus;⓪ FORWARD ReceiveLinkMgmt (VAR packet: ptrPacket): ReceiveStatus;⓪ FORWARD IR_Handler;⓪ FORWARD GetFrame;⓪ ⓪ PROCEDURE NewPacketBuffer;⓪"VAR p, prev, last: ptrPacket; sr: CARDINAL;⓪"BEGIN⓪$ASSEMBLER⓪(MOVE    SR,sr(A6)⓪(MOVE    #$2500,SR⓪$END;⓪$NEW (p);⓪$IF p # NIL THEN⓪&IF packetBuffers = 0 THEN⓪(headPacket:= p;⓪(tailPacket:= p;⓪(last:= p⓪&ELSE⓪(prev:= headPacket;⓪(WHILE prev^.next # tailPacket DO⓪*prev:= prev^.next⓪(END;⓪(last:= prev^.next;⓪(prev^.next:= p⓪&END;⓪&INC (packetBuffers);⓪&WITH p^ DO⓪(next:= last;⓪(status:= undefined;⓪(no:= packetBuffers⓪&END;⓪$END;⓪$ASSEMBLER⓪(MOVE    sr(A6),SR⓪$END;⓪"END NewPacketBuffer;⓪ ⓪ PROCEDURE ResetReceiveBuffer;⓪"BEGIN⓪$tailPacket:= headPacket⓪"END ResetReceiveBuffer;⓪ ⓪ PROCEDURE Init (hint: BYTE; server: BOOLEAN);⓪"VAR i: CARDINAL;⓪"BEGIN⓪$backoff:= 0;⓪$deferHistory:= bitVector {};⓪$collsnHistory:= bitVector {};⓪$deferCount:= 0;⓪$collsnCount:= 0;⓪$⓪$WHILE packetBuffers < 2 DO⓪&NewPacketBuffer⓪$END;⓪$⓪$TimerA.Init;⓪$⓪$(**** SCC initialisieren ****)⓪$(*⓪%* Die Clock an RTxCA ist 3.672 MHz, benötigte Baudrate ist 230400 Bit/s.⓪%* Dazu müßte die Clock auf 1/16 geteilt werden.⓪%* Da für Receive DPLL verwendet wird, und DPLL den 16fachen Clk⓪%* braucht, wird trotzdem kein Teiler verwendet. Stattdessen wird⓪%* über den BRG geteilt.⓪%*⓪%* Der SCC arbeitet im Interrupt-Betrieb. Es wird der Non-Auto-Vektor-⓪%* Modus verwendet, auf Adr. $360. Der IR läuft im Level 5.⓪%* Da nur eine einzige IR-Quelle benutzt wird (IR on 1st Rx Char or⓪%* special condition), wird die vector-includes-status-Option nicht⓪%* verwerdet.⓪%*)⓪$GIOffBit ($7F);⓪$SCC.Reset ();⓪$(* X1 clock mode, SDLC mode, no parity *)⓪$SCC.SetReg ( 4, 00100000%);⓪$(* FM0 encoding, CRC preset 1 *)⓪$SCC.SetReg (10, 11100000%);⓪$(* Address: 0 *)⓪$SCC.SetReg ( 6, 0);⓪$(* SDCL flag *)⓪$SCC.SetReg ( 7, 01111110%);⓪$(* time constant: $0006 *)⓪$SCC.SetReg (12, 6);⓪$SCC.SetReg (13, 0);⓪$(* FM mode *)⓪$SCC.SetReg (14, 11000000%);⓪$(* 8 Rx Bits *)⓪$SCC.SetReg ( 3, 11010000%);⓪$⓪$(* Rx Clk: DPLL, Tx Clk: BRG *)⓪$SCC.SetReg (11, 01110000%);⓪$⓪$(* activate DPLL, enable BRG *)⓪$SCC.SetReg (14, 00100001%);⓪$⓪$(* 8 Tx Bits, SDLC CRC check *)⓪$SCC.SetReg ( 5, 01100000%);⓪$⓪$(* *** IR vorbereiten *** *)⓪$IR_Vector:= IR_Handler;⓪$SCC.SetReg ( 2, SHORT (LONGCARD (ADR (IR_Vector)) DIV 4)); (* IR-Vektor *)⓪$SCC.SetReg (15, 00000000%);⓪$SCC.SetReg ( 1, 00001000%); (* IR on 1st Rx or special condition *)⓪$SCC.SetReg ( 9, 00001000%); (* Enable IR (no VIS) *)⓪$⓪$enableRx;⓪$⓪$AcquireAddress (hint, server)⓪"END Init;⓪ ⓪ PROCEDURE AcquireAddress (hint: BYTE; server: BOOLEAN);⓪ ⓪"VAR maxTrys, trys: CARDINAL;⓪&ok: BOOLEAN;⓪&ENQframe: aFrame;⓪"⓪"BEGIN⓪$IF CHAR(hint) > 0C THEN⓪&myAddress:= hint⓪$ELSIF server THEN⓪&myAddress:= SHORT (random (127) + 128)⓪$ELSE⓪&myAddress:= SHORT (random (127) + 1)⓪$END;⓪$setAddress (myAddress);⓪$trys:= 0;⓪$⓪$fAdrValid:= FALSE;⓪$IF server THEN maxTrys:= wksTries * 6 ELSE maxTrys:= wksTries END;⓪$fAdrInUse:= FALSE;⓪$⓪$WHILE trys < maxTrys DO⓪&IF (TransmitPacket (myAddress, lapENQ, ENQframe.dataField, 0) = transmitOK)⓪&OR fAdrInUse THEN⓪(IF server THEN⓪*myAddress:= SHORT (random (127) + 128)⓪(ELSE⓪*myAddress:= SHORT (random (127) + 1)⓪(END;⓪(setAddress (myAddress);⓪(trys:= 0;⓪&ELSE⓪(INC (trys)⓪&END⓪$END; (* WHILE *)⓪$⓪$fAdrValid:= TRUE⓪"END AcquireAddress;⓪ ⓪ PROCEDURE TransmitPacket (    dstParam: anAddress;⓪>typeParam: aLAPtype;⓪:REF dataParam: aDataField;⓪>dataLength: INTEGER): TransmitStatus;⓪"BEGIN⓪$IF fAdrInUse THEN⓪&RETURN dupAddress⓪$ELSE⓪&WITH outgoingPacket DO⓪(dstAddr:= dstParam;⓪(srcAddr:= myAddress;⓪(lapType:= typeParam;⓪(dataField:= dataParam (*!!! hier werden 600 Byte kopiert *)⓪&END;⓪&outgoingLength:= dataLength + 3;⓪&RETURN TransmitLinkMgmt ()⓪$END⓪"END TransmitPacket;⓪ ⓪ PROCEDURE TransmitLinkMgmt (): TransmitStatus;⓪"⓪"VAR deferTries, collsnTries, lclbackoff: INTEGER;⓪&dummy, fBroadCast, fENQ: BOOLEAN;⓪&RTSframe: aFrame;⓪&rcvdFrame: FrameStatus;⓪&rcvdPacket: ptrPacket;⓪&status: TransmitStatus;⓪&sr: CARDINAL;⓪"⓪"BEGIN⓪$WITH RTSframe DO⓪&dstAddr:= outgoingPacket.dstAddr;⓪&srcAddr:= myAddress;⓪&lapType:= lapRTS⓪$END;⓪$⓪$fBroadCast:= (outgoingPacket.dstAddr = BYTE($FF));⓪$fENQ:= (outgoingPacket.lapType = lapENQ);⓪$⓪$IF BitCount (collsnHistory) > 2 THEN⓪&backoff:= min (max (backoff*2,2), 16);⓪&collsnHistory:= bitVector {}⓪$ELSIF BitCount (deferHistory) < 2 THEN⓪&backoff:= backoff DIV 2;⓪&deferHistory:= bitVector {}⓪$END;⓪$⓪$collsnHistory:= SHIFT (collsnHistory, 1);⓪$deferHistory:= SHIFT (deferHistory, 1);⓪$⓪$deferTries:= 0;⓪$collsnTries:= 0;⓪$lclbackoff:= backoff;⓪$⓪$LOOP⓪&REPEAT⓪(IF carrierSense () THEN⓪*lclbackoff:= max (lclbackoff, 2);⓪*INCL (deferHistory, 0);⓪*⓪*IF NOT TimerA.DelayBytesUntil (maxFrameSize, carrierSense, FALSE) THEN⓪,(* carrierSense () = TRUE *)⓪,resetRx()⓪*END;⓪(END;⓪(⓪(dummy:= TimerA.DelayµsUntil (minIDGtime, carrierSense, TRUE)⓪&UNTIL NOT carrierSense ();⓪&⓪&resetMissingClock ();⓪&⓪&dummy:= TimerA.DelayµsUntil (random (lclbackoff) * IDGslottime, carrierSense, TRUE);⓪&⓪&IF carrierSense () OR missingClock () THEN⓪(INC (deferCount);⓪(lclbackoff:= max (lclbackoff, 2);⓪(INCL (deferHistory, 0);⓪(IF deferTries >= maxDefers THEN⓪*status:= excessDefers; EXIT⓪(END;⓪(INC (deferTries);⓪&ELSE⓪((*$D-*)⓪(fCTSexpected:= TRUE;⓪((*!!! da ggf. noch andere IRs kamen:⓪*ResetReceiveBuffer;⓪(*)⓪(IF fENQ THEN⓪*TransmitFrame (outgoingPacket, 3)⓪(ELSE⓪*TransmitFrame (RTSframe, 3)⓪(END;⓪(rcvdFrame:= ReceiveFrame (rcvdPacket);⓪(fCTSexpected:= FALSE;⓪(⓪(IF rcvdPacket # NIL THEN⓪*InOut.WriteCard (rcvdPacket^.no, 1); InOut.Write (' ');⓪*WriteFrame (rcvdPacket^, 20);⓪(END;⓪(⓪(CASE rcvdFrame OF⓪(|badframeCRC, badframeSize, badframeType, overrunError, underrunError:⓪*Wr ('Answer: >frameError<');⓪(|lapACKframe:⓪*Wr ('Answer: >ACKframe<')⓪(|lapENQframe:⓪*Wr ('Answer: >ENQframe<');⓪(|lapRTSframe:⓪*Wr ('Answer: >RTSframe<');⓪(|lapDATAframe:⓪*Wr ('Answer: >DATAframe<');⓪(|noFrame:⓪*(*IF fAdrValid THEN Wr ('Answer: no frame!') END*)⓪(ELSE⓪*Wr ('Answer: unknown frame!');⓪(END;⓪(⓪((*$D=*)⓪(IF fAdrInUse THEN⓪*status:= dupAddress; EXIT⓪(ELSIF (rcvdFrame = noFrame) & fBroadCast⓪(OR (rcvdFrame = lapCTSframe) & ~fENQ & ~fBroadCast THEN⓪*TransmitFrame (outgoingPacket, outgoingLength);⓪*status:= transmitOK; EXIT⓪(END;⓪(⓪(INC (collsnCount);⓪(INCL (collsnHistory, 0);⓪(IF collsnTries >= maxCollsns THEN⓪*status:= excessCollsns; EXIT⓪(END;⓪(lclbackoff:= min (max (lclbackoff*2,2), 16);⓪(INC (collsnTries)⓪&END⓪$END (* LOOP *);⓪$RETURN status⓪"END TransmitLinkMgmt;⓪ (*$D-*)⓪ ⓪ PROCEDURE TransmitFrameAsm;⓪"(*$L-*)⓪"BEGIN⓪$ASSEMBLER⓪(; A0: ^Daten, D0: Anzahl, A1: CTLA, A2: $FFFFFA00⓪(; enableTxDrivers⓪(MOVE.B  #5,(A1)⓪(MOVE.B  #setRTS,(A1)⓪(⓪(; Pause f. Sync-Pulse (1 Bit: 1.5 * bitTime (6.51µs) = 16 Zyklen)⓪(MOVE.B  #$DF,$0B(A2)    ; IPRA: Clear Timer-A Pending Bit⓪(MOVE.B  #4,$1F(A2)      ; TADR: Set Timer Count⓪(MOVE.B  #1,$19(A2)      ; TACR: Timer Start (Teiler: 1/4)⓪%l: BTST    #5,$0B(A2)      ; IPRA⓪(BEQ     l⓪(MOVE.B  #$00,$19(A2)    ; TACR: Timer Stop⓪(⓪(; disableTxDrivers⓪(MOVE.B  #5,(A1)⓪(MOVE.B  #$60,(A1)⓪(⓪(; Pause f. Sync-Pulse (1 Bit: 1.5 * bitTime (6.51µs) = 16 Zyklen)⓪(MOVE.B  #$DF,$0B(A2)    ; IPRA: Clear Timer-A Pending Bit⓪(MOVE.B  #4,$1F(A2)      ; TADR: Set Timer Count⓪(MOVE.B  #1,$19(A2)      ; TACR: Timer Start (Teiler: 1/4)⓪%l2 BTST    #5,$0B(A2)      ; IPRA⓪(BEQ     l2⓪(MOVE.B  #$00,$19(A2)    ; TACR: Timer Stop⓪(⓪(; enableTxDrivers, enableTx⓪(MOVE.B  #5,(A1)⓪(MOVE.B  #txEnable,(A1)⓪(⓪(; disableRx⓪(MOVE.B  #3,(A1)⓪(MOVE.B  #$D0,(A1)⓪(⓪(; 2 * txFlag⓪(; Delay: 2 * 1.5 * byteTime (39µs) = 116 Zyklen⓪(MOVE.B  #$DF,$0B(A2)    ; IPRA: Clear Timer-A Pending Bit⓪(MOVE.B  #70,$1F(A2)     ; TADR: Set Timer Count⓪(MOVE.B  #1,$19(A2)      ; TACR: Timer Start (Teiler: 1/4)⓪%l3 BTST    #5,$0B(A2)      ; IPRA⓪(BEQ     l3⓪(MOVE.B  #$00,$19(A2)    ; TACR: Timer Stop⓪(⓪(; resetCRC⓪(MOVE.B  #$80,(A1)⓪(⓪%nextChar:⓪(; TxChar⓪(MOVE.B  (A0)+,2(A1)⓪(NOP⓪(NOP⓪%notEmpty:⓪(BTST    #2,(A1)⓪(BEQ     notEmpty⓪(SUBQ    #1,D0⓪(BNE     nextChar⓪(⓪(; resetUnderrun⓪(MOVE.B  #$C0,(A1)⓪(⓪(; TxFCS: wait for underrun⓪%notUnder:⓪(BTST    #6,(A1)⓪(BEQ     notUnder⓪(⓪(; TxFlag (?)⓪%notEmpty2:⓪(BTST    #2,(A1)⓪(BEQ     notEmpty2⓪(⓪(; enableTxDrivers, disableTx⓪(MOVE.B  #5,(A1)⓪(MOVE.B  #setRTS,(A1)⓪(⓪(; txONEs (?)⓪(; Delay: 1.5 * byteTime (39µs) = 58 Zyklen⓪(MOVE.B  #$DF,$0B(A2)    ; IPRA: Clear Timer-A Pending Bit⓪(MOVE.B  #35,$1F(A2)     ; TADR: Set Timer Count⓪(MOVE.B  #1,$19(A2)      ; TACR: Timer Start (Teiler: 1/4)⓪%l4 BTST    #5,$0B(A2)      ; IPRA⓪(BEQ     l4⓪(MOVE.B  #$00,$19(A2)    ; TACR: Timer Stop⓪(⓪(; disableTxDrivers⓪(MOVE.B  #5,(A1)⓪(MOVE.B  #$60,(A1)⓪(⓪(; resetMissingClock⓪(MOVE.B  #14,(A1)⓪(MOVE.B  #$41,(A1)⓪(⓪(; enableRx⓪(MOVE.B  #3,(A1)⓪(MOVE.B  #rxEnable,(A1)⓪$END;⓪"END TransmitFrameAsm;⓪"(*$L=*)⓪ ⓪ PROCEDURE TransmitFrame (REF frame: aFrame; frameSize: CARDINAL);⓪"(*$L-*)⓪"BEGIN⓪$ASSEMBLER⓪(MOVE    SR,D2⓪(ORI     #$2700,SR⓪(MOVEA.W #CTLA,A1⓪(MOVEA.W #$FA00,A2⓪(MOVE.W  -(A3),D0⓪(MOVE.L  -(A3),A0⓪(JSR     TransmitFrameAsm⓪(MOVE    D2,SR⓪$END;⓪"END TransmitFrame;⓪"(*$L=*)⓪ ⓪ PROCEDURE ReceivePacket (VAR dstParam: anAddress;⓪9VAR srcParam: anAddress;⓪9VAR typeParam: aLAPtype;⓪9VAR dataParam: aDataField;⓪9VAR dataLength: INTEGER);⓪"VAR status: ReceiveStatus; packet: ptrPacket;⓪"BEGIN⓪$REPEAT UNTIL (ReceiveLinkMgmt (packet) = receiveOK) OR InOut.KeyPressed ();⓪$WITH packet^.frame DO⓪&dstParam:= dstAddr;⓪&srcParam:= srcAddr;⓪&typeParam:= lapType;⓪&dataParam:= dataField (*!!! hier werden 600 Byte kopiert -> Ptr verw.*)⓪$END;⓪"END ReceivePacket;⓪ ⓪ PROCEDURE ReceiveLinkMgmt (VAR packet: ptrPacket): ReceiveStatus;⓪"⓪"VAR status: ReceiveStatus;⓪&rcvdStatus: FrameStatus;⓪&CTSframe, ACKframe: aFrame;⓪&sr: CARDINAL;⓪"⓪"BEGIN⓪$ASSEMBLER⓪(MOVE    SR,sr(A6)⓪(MOVE    #$2500,SR⓪$END;⓪$status:= receiving;⓪$REPEAT⓪&rcvdStatus:= ReceiveFrame (packet);⓪&IF rcvdStatus # noFrame THEN⓪(InOut.WriteCard (packet^.no, 1); InOut.Write (' ');⓪(WriteFrame (packet^,99);⓪(InOut.WriteLn;⓪(WriteStatus (rcvdStatus); InOut.WriteLn;⓪&END;⓪&CASE rcvdStatus OF⓪&|badframeCRC, badframeSize, badframeType, overrunError, underrunError:⓪(status:= frameError⓪&|lapACKframe:⓪&|lapENQframe:⓪(IF fAdrValid THEN⓪*WITH ACKframe DO⓪,dstAddr:= packet^.frame.srcAddr;⓪,srcAddr:= myAddress;⓪,lapType:= lapACK⓪*END;⓪*TransmitFrame (ACKframe, 3);⓪(ELSE⓪*fAdrInUse:= TRUE⓪(END;⓪(status:= nullReceive⓪&|lapRTSframe:⓪((* wird nun schon beim Empfang erledigt *)⓪(HALT⓪((*⓪*IF fAdrValid THEN⓪,WITH CTSframe DO⓪.dstAddr:= headPacket^.frame.srcAddr;⓪.srcAddr:= myAddress;⓪.lapType:= lapCTS⓪,END;⓪,TransmitFrame (CTSframe, 3);⓪*ELSE⓪,fAdrInUse:= TRUE;⓪,status:= nullReceive⓪*END;⓪(*)⓪&|lapDATAframe:⓪(IF fAdrValid THEN⓪*status:= receiveOK⓪(ELSE⓪*fAdrInUse:= TRUE;⓪*status:= nullReceive⓪(END;⓪&|noFrame:⓪(status:= nullReceive⓪&ELSE⓪&END⓪$UNTIL status # receiving;⓪$ASSEMBLER⓪(MOVE    sr(A6),SR⓪$END;⓪$RETURN status⓪"END ReceiveLinkMgmt;⓪ ⓪ PROCEDURE ReceiveFrame (VAR packet: ptrPacket): FrameStatus;⓪"⓪"VAR status: FrameStatus;⓪ ⓪"BEGIN⓪$ASSEMBLER⓪(MOVEA.W #CTLA,A1⓪(MOVEA.W #$FA00,A2⓪(MOVE.L  tailPacket,A0⓪(⓪(; *** warten auf Frame-Empfang (IR o. Polling) ***⓪(⓪(MOVEQ   #0,D1⓪(⓪$l1: MOVEQ   #maxIFGtime DIV 4,D0⓪(MOVE.B  #$DF,$0B(A2)    ; IPRA: Clear Timer-A Pending Bit⓪(MOVE.B  D0,$1F(A2)      ; TADR: Set Timer Count⓪(MOVE.B  #2,$19(A2)      ; TACR: Timer Start (Teiler: 1/10)⓪$l0: ; zuerst prüfen, ob evtl. noch ein Frame zu pollen ist,⓪(; auch wenn noch weitere Pakete schon im Puffer warten.⓪(;BTST    #0,(A1)⓪(MOVE.B  #3,(A1)⓪(BTST.B  #5,(A1)         ; RR3: Rx IR pending?⓪(BNE     pollFrame⓪(CMPA.L  headPacket,A0⓪(BNE     gotFrame⓪(BTST    #5,$0B(A2)      ; time over?⓪(BEQ     l0⓪(; IR-Receive nochmal prüfen, falls IR zw. vorigem CMP und Time-Chk kam.⓪(CMPA.L  headPacket,A0⓪(BNE     gotFrame⓪(⓪((*⓪(TST     test⓪(BEQ     timeout⓪(⓪(ADDQ    #1,D1⓪(BRA     l1⓪(*)⓪(⓪$timeout:⓪(; time out⓪(MOVE.B  #$00,$19(A2)    ; TACR: Timer Stop⓪(MOVE.L  packet(A6),A1⓪(CLR.L   (A1)⓪(MOVE    #noFrame,status(A6)⓪(BRA.W   exit2⓪(⓪$gotFrame:⓪(MOVE.B  #$00,$19(A2)    ; TACR: Timer Stop⓪(BRA     exit⓪(⓪$pollFrame:⓪(MOVE    SR,D2⓪(ORI     #$0700,SR⓪(MOVE.B  #$00,$19(A2)    ; TACR: Timer Stop⓪(JSR     GetFrame⓪(MOVE.B  #1,(A1)⓪(MOVE.B  #$08,(A1)⓪(; MOVE.B  #2,4(A1)⓪(; TST.B   4(A1)                   ; RR2B⓪(MOVE    D2,SR⓪(⓪$exit:⓪(MOVE.L  tailPacket,A0⓪(MOVE.L  packet(A6),A1⓪(MOVE.L  A0,(A1)⓪(MOVE    aPacket.status(A0),status(A6)⓪(MOVE.L  aPacket.next(A0),tailPacket⓪(⓪$exit2:⓪$END;⓪$RETURN status ⓪"END ReceiveFrame;⓪ ⓪ PROCEDURE IR_Handler;⓪"(*$L-*)⓪"BEGIN⓪$ASSEMBLER⓪(ORI     #$0700,SR⓪(MOVEM.L A0-A2/D0-D1,-(A7)⓪(⓪(MOVEA.W #$FA00,A2⓪(MOVEA.W #CTLA,A1⓪(JSR     GetFrame⓪(⓪(ADDQ.W  #1,Interrupts⓪(⓪(MOVEM.L (A7)+,A0-A2/D0-D1⓪(RTE⓪$END;⓪"END IR_Handler;⓪"(*$L=*)⓪ ⓪ PROCEDURE GetFrame;⓪"(*$L-*)⓪"BEGIN⓪$ASSEMBLER⓪(MOVE.B  2(A1),D0                ; 1. char sofort holen⓪(MOVE.L  headPacket,A0⓪(MOVE.B  D0,aPacket.frame(A0)⓪(⓪(MOVE.B  #2,4(A1)⓪(BTST.B  #0,4(A1)                ; RR2B⓪(BNE     specCond⓪(⓪(MOVEQ   #100,D1⓪&wait2:⓪(BTST    #0,(A1)⓪(DBNE    D1,wait2⓪(MOVE.B  2(A1),aPacket.frame+1(A0)⓪(⓪(MOVEQ   #2,D0⓪(BRA     nextChar⓪(⓪$specCond:⓪(MOVE #$2500,SR BREAK⓪(⓪$again:⓪(CLR     D0⓪(⓪$loop2:⓪(; overrun?⓪(MOVE.B  #1,(A1)   ; RR1⓪(BTST.B  #5,(A1)⓪(BEQ     noOverrun⓪(⓪(MOVE    D0,aPacket.length(A0)⓪(MOVE.W  #overrunError,aPacket.status(A0)⓪(BRA.W   exit2⓪(⓪$timeOut:⓪(MOVE    D0,aPacket.length(A0)⓪(MOVE.W  #noFrame,aPacket.status(A0)⓪(BRA.W   exit2⓪(⓪$noOverrun:⓪(MOVEQ   #100,D1⓪&wait4:⓪(BTST    #0,(A1)⓪(DBNE    D1,wait4⓪(BEQ     timeOut⓪(⓪((*⓪(BTST.B  #0,(A1)   ; Data avail?⓪(BEQ     noDataNow ; !!!timeout berücksichtigen⓪(*)⓪(⓪(; *** read data ***⓪(CMPI.W  #maxFrameSize,D0        ; incomingLength⓪(BCS     getChar⓪(⓪$sizeError:⓪(MOVE    D0,aPacket.length(A0)⓪(MOVE.W  #badframeSize,aPacket.status(A0)⓪(BRA.W   exit2⓪(⓪$getChar:⓪(; headPacket^.frame.rawData [incomingLength]:= rxData ()⓪(MOVE.B  2(A1),aPacket.frame(A0,D0.W)  ; RR8⓪(ADDQ.W  #1,D0             ; incomingLength⓪(⓪$nextChar:⓪$noDataNow:⓪(; end of frame?⓪(MOVE.B  #1,(A1)   ; RR1⓪(TST.B   (A1)⓪(BPL     loop2⓪(⓪(; CRC OK?⓪(MOVE.B  #1,(A1)   ; RR1⓪(BTST.B  #6,(A1)⓪(BEQ     crcOK⓪(⓪(MOVE    D0,aPacket.length(A0)⓪(MOVE.W  #badframeCRC,aPacket.status(A0)⓪(BRA.W   exit2⓪(⓪$crcOK:⓪(SUBQ.W  #2,D0           ; incomingLength⓪(MOVE    D0,aPacket.length(A0)⓪(CMPI.W  #minFrameSize,D0⓪(BCS     sizeError⓪(⓪((* Der folgende Teil kann auch aus dem IR-Handler herausgenommen werden*)⓪(⓪(; *** frameDone ***⓪(TST.W   fAdrValid⓪(BEQ     notValid⓪(⓪(MOVE.B  aPacket.frame.lapType(A0),D0⓪(BMI     ctrlFrame⓪(⓪(MOVE.W  #lapDATAframe,aPacket.status(A0)⓪(BRA.W   exit2⓪(⓪&ctrlFrame:⓪(CMPI.B  #lapENQ,D0⓪(BEQ     isENQ⓪(CMPI.B  #lapACK,D0⓪(BEQ     isACK⓪(CMPI.B  #lapRTS,D0⓪(BEQ     isRTS⓪(CMPI.B  #lapCTS,D0⓪(BEQ     isCTS⓪&badFrame:⓪(MOVE.W  #badframeType,aPacket.status(A0)⓪(BRA     exit2⓪&isENQ:⓪(MOVE.W  #lapENQframe,aPacket.status(A0)⓪(BRA     exit2⓪&isACK:⓪(MOVE.W  #lapACKframe,aPacket.status(A0)⓪(MOVE.W  #1,fAdrInUse⓪(BRA     exit2⓪&isRTS:⓪(MOVE.W  #lapRTSframe,aPacket.status(A0)⓪(BRA     exit2⓪&isCTS:⓪(MOVE.W  #lapCTSframe,aPacket.status(A0)⓪(TST.W   fCTSexpected⓪(BNE     exit2⓪(MOVE.W  #1,fAdrInUse⓪(BRA     badFrame⓪(⓪¬Valid:⓪(CMPI.B  #$FF,aPacket.frame.dstAddr(A0)⓪(BEQ     exit2⓪(⓪(MOVE    #1,fAdrInUse⓪(MOVE.W  #noFrame,aPacket.status(A0)⓪(⓪$exit2:⓪(⓪(CMPI.W  #lapRTSframe,aPacket.status(A0)⓪(BNE     noRTS⓪(⓪(; CTS senden, falls kein Broadcast⓪(CMPI.B  #$FF,aPacket.frame.dstAddr(A0)⓪(BEQ     noCTS⓪(MOVE.B  #lapCTS,-(A7)⓪(MOVE.B  aPacket.frame.srcAddr(A0),D0⓪(LSL     #8,D0⓪(MOVE.B  myAddress,D0⓪(MOVE.W  D0,-(A7)⓪(MOVE.L  A7,A0⓪(MOVE.W  #3,D0⓪(JSR     TransmitFrameAsm⓪(ADDQ.L  #4,A7⓪(MOVE.L  headPacket,A0⓪&noCTS:⓪(MOVE.W  #noFrame,aPacket.status(A0)⓪(⓪&noRTS:⓪(⓪(; resetRx⓪(MOVE.B  #3,(A1)⓪(MOVE.B  #$D0,(A1)       ; disableRx⓪(⓪(MOVEQ   #2,D0⓪&flushFIFO:⓪(TST.B   2(A1)⓪(DBRA    D0,flushFIFO⓪(⓪(; resetMissingClock⓪(MOVE.B  #14,(A1)⓪(MOVE.B  #$41,(A1)⓪(⓪(MOVE.B  #3,(A1)⓪(MOVE.B  #rxEnable,(A1)  ; enableRx⓪(⓪(; reset error⓪(MOVE.B  #$30,(A1)⓪(⓪(MOVE.B  #$20,(A1)         ; enable IR on next Rx⓪(⓪(; resetMissingClock⓪(MOVE.B  #14,(A1)⓪(MOVE.B  #$41,(A1)⓪(⓪(ADDQ.W  #1,FramesReceived⓪(⓪(MOVE.L  aPacket.next(A0),A0⓪(MOVE.L  A0,headPacket⓪(⓪(; reset IUS⓪(MOVE.B  #$38,(A1)⓪(⓪(; more IRs?⓪((* hat wohl keinen Sinn, da das nicht so gemeldet wird⓪*MOVE.B  #3,(A1)⓪*TST.B   (A1)            ; RR3⓪*BNE     again⓪(*)⓪(BTST    #0,(A1)⓪(BNE     again⓪(⓪(; MOVE.B  #1,(A1)⓪(; MOVE.B  #$08,(A1)         ; enable IR on first Rx⓪$END⓪"END GetFrame;⓪"(*$L=*)⓪ ⓪ BEGIN⓪"packetBuffers:= 0;⓪ END (* MODULE *) ALAP;⓪ ⓪ (*****************************************************************************)⓪ ⓪ TYPE BS = SET OF [0..7];⓪%RegSet = SET OF [0..15];⓪ ⓪ CONST ReadRegs  = RegSet {0,1,2,3,8,10,12,13,15};⓪&WriteRegs = RegSet {0..15};⓪&⓪&RegsToDisplay = RegSet {0,1,2,3,8,10,12,13,15};⓪&⓪ ⓪ PROCEDURE WriteReg (n: CARDINAL);⓪"VAR reg: CARDINAL;⓪"BEGIN⓪$reg:= SCC.Reg (n);⓪$WriteNum (reg, 16, 2, '0');⓪$WriteString ('  ');⓪$WriteNum (reg, 2, 8, '0');⓪"END WriteReg;⓪ ⓪ ⓪ VAR ch: CHAR;⓪$rxIdx, n, c: CARDINAL;⓪$lc: LONGCARD;⓪$i: INTEGER;⓪$ssp, li: LONGINT;⓪$redraw, quit, ok, b: BOOLEAN;⓪$by: BS;⓪$⓪$packet: ALAP.ptrPacket;⓪$dstParam, srcParam: ALAP.anAddress;⓪$typeParam: ALAP.aLAPtype;⓪$dataParam: ALAP.aDataField;⓪$txStatus: ALAP.TransmitStatus;⓪$frameStatus: ALAP.FrameStatus;⓪$dataLength: INTEGER;⓪ ⓪ BEGIN⓪"WritePg;⓪"ssp:= Super (0);⓪"⓪"(*⓪"WriteLn;⓪"WriteString ('Start...');⓪"FOR c:= 1 TO 5 DO⓪$FOR n:= 1 TO 5*1000 DO⓪&ASSEMBLER⓪(MOVEA.W #$FA00,A2⓪(MOVEQ   #50,D0⓪(MOVE.B  #$DF,$0B(A2)    ; IPRA: Clear Timer-A Pending Bit⓪(MOVE.B  D0,$1F(A2)      ; TADR: Set Timer Count⓪(MOVE.B  #2,$19(A2)      ; TACR: Timer Start (Teiler: 1/10)⓪$l0: BTST    #5,$0B(A2)      ; time over?⓪(BEQ     l0⓪(MOVE.B  #$00,$19(A2)    ; TACR: Timer Stop⓪&END;⓪$END;⓪"END;⓪"WriteString ('Stop!');⓪"WriteLn;⓪"*)⓪"⓪"WriteLn;⓪"WriteString ('Init...');⓪"WriteLn;⓪"⓪"ALAP.Init (0, FALSE);⓪"⓪"ALAP.NewPacketBuffer;⓪"ALAP.NewPacketBuffer;⓪"ALAP.NewPacketBuffer;⓪"ALAP.NewPacketBuffer;⓪"⓪"WriteString ('OK');⓪"WriteLn;⓪"⓪"rxIdx:= 0;⓪"redraw:= TRUE;⓪"quit:= FALSE;⓪"REPEAT⓪$IF redraw THEN⓪&GotoXY (4,0);⓪&WriteString (' interrupts');⓪&GotoXY (4,1);⓪&WriteString (' frames received');⓪&GotoXY (0,2);⓪&FOR n:= 0 TO 15 DO⓪(IF n IN ReadRegs THEN⓪*WriteString ('Reg '); WriteNum (n, 16, 1, '0'); WriteString (': '); WriteLn;⓪(END⓪&END;⓪&WriteString (VT52.Seq[clearEOS]);⓪&⓪&c:= 2;⓪&FOR n:= 0 TO 15 DO⓪(IF n IN ReadRegs THEN⓪*IF n IN RegsToDisplay THEN GotoXY (7,c); WriteReg (n) END;⓪*INC (c);⓪(END;⓪&END;⓪&⓪&GotoXY (0, 11);⓪&WriteString ('myAddress: '); WriteHex (LONG (ALAP.myAddress), 3);⓪&⓪&redraw:= FALSE⓪$END;⓪$GotoXY (0,0);⓪$WriteCard (ALAP.Interrupts, 4);⓪$GotoXY (0,1);⓪$WriteCard (ALAP.FramesReceived, 4);⓪$⓪$IF ALAP.headPacket # ALAP.tailPacket THEN⓪&frameStatus:= ALAP.ReceiveFrame (packet);⓪&GotoXY (40, rxIdx);⓪&WriteCard (rxIdx, 2);⓪&INC (rxIdx);⓪&WriteString (': ');⓪&ALAP.WriteFrame (packet^, 5);⓪&InOut.WriteCard (packet^.no, 1); InOut.Write (' ');⓪&ALAP.WriteStatus (packet^.status);⓪$END;⓪$⓪$IF KeyPressed() THEN⓪&GotoXY (0,14);⓪&WriteString (VT52.Seq[clearEOS]);⓪&WriteLn;⓪&Read (ch); ch:= CAP (ch);⓪&IF ch = 'Q' THEN⓪(quit:= TRUE;⓪&ELSIF ch = 'T' THEN⓪(WriteLn;⓪(WriteString ('Transmitting...');⓪(WriteLn;⓪(txStatus:= ALAP.TransmitPacket (BYTE($FF), BYTE($81), dataParam, 0);⓪(ALAP.fAdrInUse:= FALSE;⓪(WriteString ('Status: ');⓪(CASE txStatus OF⓪(| ALAP.transmitOK: WriteString ('transmitOK')⓪(| ALAP.excessDefers: WriteString ('excessDefers')⓪(| ALAP.excessCollsns: WriteString ('excessCollsns')⓪(| ALAP.dupAddress: WriteString ('dupAddress')⓪(END;⓪(WriteLn;⓪&ELSIF ch = 'R' THEN⓪(WriteLn;⓪(WriteString ('Receiving...');⓪(WriteLn;⓪(ALAP.ReceivePacket (dstParam, srcParam, typeParam, dataParam, dataLength);⓪(IF InOut.KeyPressed () THEN⓪*WriteString ('Aborted');⓪*Read (ch)⓪(ELSE⓪*WriteString ('OK');⓪(END⓪&ELSIF ch = 'G' THEN⓪(WriteLn;⓪(WriteString ('Getting Addresses on Bus...');⓪(WriteLn;⓪(FOR n:= $15 TO $15 DO⓪*ALAP.test:= TRUE;⓪*txStatus:= ALAP.TransmitPacket (SHORT(n), BYTE($81), dataParam, 0);⓪*IF txStatus = ALAP.dupAddress THEN⓪,Write ('>'); WriteHex (n, 3); Write ('<'); WriteLn;⓪*END;⓪*ALAP.fAdrInUse:= FALSE;⓪(END;⓪(ALAP.test:= FALSE;⓪(WriteLn;⓪&ELSIF ch = ' ' THEN⓪(WritePg;⓪(rxIdx:= 0;⓪(redraw:= TRUE⓪&ELSIF ch = 'I' THEN⓪(WriteString ('Init...');⓪(WriteLn;⓪(ALAP.Init (0, FALSE);⓪&ELSIF (ch >= '0') & (ch <= '9') OR (ch >= 'A') & (ch <= 'F') THEN⓪(Write (10C); (* BS *)⓪(n:= ORD (ch) - ORD ('0'); IF n > 9 THEN DEC (n, 7) END;⓪(IF n IN WriteRegs THEN⓪*WriteString ('Write Reg '); WriteNum (n, 16, 1, '0');⓪*WriteString ('? ');⓪*ReadCard (c);⓪*IF Done & (c <= 255) THEN⓪,SCC.SetReg (n, c);⓪*ELSE⓪,WriteString ('No write!'); WriteLn⓪*END⓪(END⓪&END;⓪$END;⓪"UNTIL quit;⓪"ssp:= Super (ssp)⓪ END LANMonitor.⓪ ə
  2. (* $FFF006F0$00006FDE$FFF006F0$FFF006F0$0000798F$FFF006F0$FFF006F0$FFF006F0$FFF006F0$FFF006F0$FFF006F0$FFF006F0$FFF006F0$FFF006F0$FFF006F0$000036BC$FFF006F0$000045ED$FFF006F0$FFF006F0$FFF006F0$00007ECF$FFF006F0$00006F5F$00006E60$00003E9D$000069AB$FFF006F0$00004BE7$FFF006F0$FFF006F0$FFF006F0$FFF006F0$FFF006F0$00006073$FFF006F0$FFF006F0$FFF006F0$00002864$00003546$FFF006F0$FFF006F0Ç$00000025T.......T.......T.......T.......T.......T.......T.......T.......T.......T.......$000088C1$0000524C$000063F9$00006429$0000640F$00000025$000036C5$000036EF$000036C5$000036EF$0000373A$FFF006F0$FFF006F0$0000369B$000036C8$00003547ÿÇé*)
  3.